#include <jni.h>
#include <string>
#include<android/log.h>

#include "yc_bluetooth_voicecontrol_MyJni.h"
#include "ima_enc.h"
#include "ima_enc.c"
#include "msbc.c"
#include "msbc.h"
#include "sbc.h"
#include "sbcdec.c"
//#include "res_8_16.h"
#include "res_8_16.c"   //只需要.c，因为.h在.c中已经include

#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>

unsigned char input[1024];
unsigned char output[1024];
short micOut[1024];

int outputLen = 256;

#define ENCODE_DATA_LEN 240
#define DECODE_DATA_LEN 57

CodecState mg = {0,0};

int frame_len;
int framelen;

//先定义
sbc_t t_sbc;
//解码的文件open值
int deOpenFileVa;

int preDeOpenFileVa;

//2019/11/7
ResStruct res;


#define TAG "MyJni" // 这个是自定义的LOG的标识
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,TAG ,__VA_ARGS__) // 定义LOGD类型
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,TAG ,__VA_ARGS__) // 定义LOGI类型
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,TAG ,__VA_ARGS__) // 定义LOGW类型
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,TAG ,__VA_ARGS__) // 定义LOGE类型
#define LOGF(...) __android_log_print(ANDROID_LOG_FATAL,TAG ,__VA_ARGS__) // 定义LOGF类型


// jstring To char*  Java字符串-->C字符串
char* jstringTostring(JNIEnv* env, jstring jstr)
{
    char* rtn = NULL;
    jclass clsstring = env->FindClass("java/lang/String");
    jstring strencode = env->NewStringUTF("utf-8");
    jmethodID mid = env->GetMethodID(clsstring, "getBytes", "(Ljava/lang/String;)[B");
    jbyteArray barr = (jbyteArray)env->CallObjectMethod(jstr, mid, strencode);
    jsize alen = env->GetArrayLength(barr);
    jbyte* ba = env->GetByteArrayElements(barr, JNI_FALSE);
    if (alen > 0)
    {
        rtn = (char*)malloc(alen + 1);
        memcpy(rtn, ba, alen);
        rtn[alen] = 0;
    }
    env->ReleaseByteArrayElements(barr, ba, 0);
    return rtn;
}


/**
 * 两数相乘
 */
extern "C"
JNIEXPORT jint JNICALL
Java_yc_bluetooth_voicecontrol_MyJni_addMethod(JNIEnv *env, jclass type, jint num1, jint num2) {

    return num1 * num2;
}

/**
 * 两数相加
 */
extern "C"
JNIEXPORT jint JNICALL
Java_yc_bluetooth_voicecontrol_MyJni_add(JNIEnv *env, jclass type, jint a, jint b) {

    return a + b;
}

/**
 * 读文件
 */
extern "C"
JNIEXPORT jstring JNICALL
Java_yc_bluetooth_voicecontrol_MyJni_readFile(JNIEnv *env, jclass type, jstring path_) {
    const char *fpFile = env->GetStringUTFChars(path_, 0);

    int fp;
    fp = open(fpFile,O_CREAT  | O_RDWR);
    int length = read(fp,input,10);

    LOGD("Java_yc_bluetooth_voicecontrol_MyJni_readFile");
    jstring  jstr = (env)->NewStringUTF((char *)input);  //直接调用NewStringUTF方法

    return jstr;
}

/**
 * 写
 */
extern "C"
JNIEXPORT jint JNICALL
Java_yc_bluetooth_voicecontrol_MyJni_writeText(
        JNIEnv *env, jclass type, jstring srcPath_,jstring message_) {
    char* dst_file = jstringTostring(env, srcPath_);
    char* write_file = jstringTostring(env, srcPath_);

    FILE *fpCpy;
    if((fpCpy=fopen(dst_file,"wb"))   ==   NULL)
    {
        printf("create wav file error\n");
        return 0;
    }

    fwrite(write_file,1,frame_len,fpCpy);
    return 1;
}

extern "C"
JNIEXPORT void JNICALL
Java_yc_bluetooth_voicecontrol_MyJni_inputAudio(
        JNIEnv *env, jclass type, jbyteArray bytes_,jint length) {
    jbyte *bytes = env->GetByteArrayElements(bytes_, NULL);

    // TODO
    env->ReleaseByteArrayElements(bytes_, bytes, 0);
}

/**
 * 初始化解码器
 */
extern "C"
JNIEXPORT jint JNICALL
Java_yc_bluetooth_voicecontrol_MyJni_initDecode(
        JNIEnv *env, jclass type, jstring path_,jstring prePath_) {

    //2019/10/18  新增，清零
    mg = {0,0};

    LOGD("进来初始化了！");
    //转换*
    char *fpFile = (char *) env->GetStringUTFChars(path_, 0);
    //获取文件句柄
    if ((deOpenFileVa = open(fpFile,O_CREAT  | O_RDWR)) == NULL){
        LOGD("文件打开失败！");
        return 0;
    }

    //转换*
    char *preFpFile = (char *) env->GetStringUTFChars(prePath_, 0);
    if ((preDeOpenFileVa = open(preFpFile,O_CREAT  | O_RDWR)) == NULL){
        LOGD("文件打开失败！");
        return 0;
    }

    //初始化解码--adpcm 4:1
    sbc_init(&t_sbc, 0L);

    //新1的初始化解码--sbc 8:1
//    sbcInitDecoder();

    //新2初始化解码--adpcm 8:1
//    sbc_init(&t_sbc, 0L);
//    ResInit(&res,SMALL_FRAM_LEN_16K8K);  //新增  SMALL_FRAM_LEN_16K8K--200

    //新3初始化解码--sbc 16:1
//    sbcInitDecoder();
//    ResInit(&res,SMALL_FRAM_LEN_16K8K);  //新增



    return 1;
}

extern "C"
JNIEXPORT jint JNICALL
Java_yc_bluetooth_voicecontrol_MyJni_encodeResult(
        JNIEnv *env, jclass type, jstring path_,jstring copyPath_) {
    //转换
//    char *fpFile = (char *) env->GetStringUTFChars(path_, 0);
//    char *fpFileCopy = (char *) env->GetStringUTFChars(copyPath_, 0);
//
//    //打开文件
//    int fp;
//    int fpCopy;
//    if ((fp = open(fpFile,O_CREAT  | O_RDWR)) == NULL){
//        return 0;
//    }
//    if ((fpCopy = open(fpFileCopy,O_CREAT  | O_RDWR)) == NULL){
//        return 0;
//    }
//
//    int readLen;
//    sbc_init(&t_sbc, 0L);
//    int position = 0;
//    while((readLen=read(fp,input,ENCODE_DATA_LEN)>0))
//    {
//        LOGD("start READ:position=%d",position);
//        framelen = sbc_encode (&t_sbc, input, ENCODE_DATA_LEN,output, 1024 ,&frame_len);
//
//        write(fpCopy,output,frame_len);
//
//        position++;
//    }
//    LOGD("encodeResult OVER FINISH");
//
//    sbc_finish(&t_sbc);
//    close(fp);
//    close(fpCopy);

    return 1;
}

extern "C"
JNIEXPORT jint JNICALL
Java_yc_bluetooth_voicecontrol_MyJni_decodeResult(
        JNIEnv *env, jclass type, jstring path_,jstring copyPath_) {
//    //转换
//    char *fpFile = (char *) env->GetStringUTFChars(path_, 0);
//    char *fpFileCopy = (char *) env->GetStringUTFChars(copyPath_, 0);
//
//    //打开文件
//    int fp;
//    int fpCopy;
//    if ((fp = open(fpFile,O_CREAT  | O_RDWR)) == NULL){
//        return 0;
//    }
//    if ((fpCopy = open(fpFileCopy,O_CREAT  | O_RDWR)) == NULL){
//        return 0;
//    }
//
//    int readLen;
//    sbc_init(&t_sbc, 0L);
//    while((readLen=read(fp,input,DECODE_DATA_LEN)>0))
//    {
//        framelen = sbc_decode (&t_sbc, input, DECODE_DATA_LEN,output, 1024 ,&frame_len);
//
//        write(fpCopy,output,frame_len);
//    }
//    sbc_finish(&t_sbc);
//    close(fp);
//    close(fpCopy);

    return 1;
}

/**
 * MSBC解码
 */
extern "C"
JNIEXPORT jbyteArray JNICALL
Java_yc_bluetooth_voicecontrol_MyJni_decodeByByte(
        JNIEnv *env, jclass type, jbyteArray bytes_) {
//    int lena = env->GetArrayLength(bytes_);
//    LOGD("MSBC解码:%d",lena);
//
//    //获取长度
//    int len = env->GetArrayLength(bytes_);
//    if (len == NULL||(len != NULL && len == 0)){
//        return 0;
//    }
//    LOGD("len:%d",len);
//
//    //数据转换
//    unsigned char* in = (unsigned char*)env->GetByteArrayElements(bytes_,0);
//
////    const char* p = (const char*)(char*)in;
//    // LOGD("lens:%x",in[0]);
//    //解码
//    framelen = sbc_decode (&t_sbc, in, len,output, 1024 ,&frame_len);
//
//    LOGD("framelen:%d",framelen);
//    //写入
//    write(deOpenFileVa,output,frame_len);
//
////    jbyte *by = (jbyte*)output;
////    jbyteArray jarray = env->NewByteArray(frame_len);
////    env->SetByteArrayRegion(jarray,0,frame_len,by);

    return NULL;
}

/**
 * ADPCM解码
 */
extern "C"
JNIEXPORT jbyteArray JNICALL
Java_yc_bluetooth_voicecontrol_MyJni_decodeByByteM1(
        JNIEnv *env, jclass type, jbyteArray bytes_) {
    //获取长度
    int len = env->GetArrayLength(bytes_);
    if (len == NULL||(len != NULL && len == 0)){
        return 0;
    }

    LOGD("len:%d",len);

    //数据转换
    unsigned char* in = (unsigned char*)env->GetByteArrayElements(bytes_,0);
    //解码
    //framelen = sbc_decode (&t_sbc, in, len,output, 1024 ,&frame_len);

    ////void decode(CodecState* state, u8* input, int numSamples, s16* output);

    //原来20一包数据
//    decode(&mg,in,40, (s16 *)output);
//    write(deOpenFileVa,output,80);

    //旧的解码方法--adpcm 4:1
    decode(&mg,in,len*2, (s16 *)output);
    write(deOpenFileVa,output,len*4);   //写入  新增  根据一包数据长度动态变化

    //新1的解码方法--sbc 8:1
//    sbcDecode(in,len,output,&outputLen);
//    LOGD("OUTPUT LEN:%d\n",outputLen);
//    for(int i=0;i<outputLen;i++){
//        LOGD("%x ",*(output+i));
//    }
//    write(deOpenFileVa,output,outputLen);

    //新2解码方法--adpcm 8:1
//    decode(&mg,in,len*2, (s16 *)output);
//    write(preDeOpenFileVa,output,len*4);
//    Res8kTo16k(&res,(s16*)output,micOut);  //新增
//    write(deOpenFileVa,micOut,len*8);   //写入  新增  根据一包数据长度动态变化

    //新3解码方法--sbc 16:1
//    sbcDecode(in,len,output,&outputLen);
//    write(preDeOpenFileVa,output,outputLen);
//    Res8kTo16k(&res,(s16*)output,micOut);
//    write(deOpenFileVa,micOut,outputLen*2);

//    jbyte *by = (jbyte*)output;
//    jbyteArray jarray = env->NewByteArray(frame_len);
//    env->SetByteArrayRegion(jarray,0,frame_len,by);

    return NULL;
}

/**
 * 完成解码
 */
extern "C"
JNIEXPORT jint JNICALL
Java_yc_bluetooth_voicecontrol_MyJni_finishDecode(JNIEnv *env, jclass type) {

    //完成解码
    sbc_finish(&t_sbc);
    //关闭
    close(deOpenFileVa);

    close(preDeOpenFileVa);

    return 1;

}